/*
* PROJECT: Happy New Year
* VERSION: 1.0
* AUTHOR: Mattias Thell
* URL: http://www.mattiasthell.com
*
* */

#pragma once

#include <vector>
#include <list>
#include <map>
#include <string>

#include <boost/shared_ptr.hpp>
#include <boost/random.hpp>

#include <hge.h>
#include <hgeparticle.h>
#include <hgefont.h>
#include <hgeanim.h>

#include "Foreach.h"
#include "Actor.hpp"
#include "TextCollection.hpp"
#include "Menu.hpp"
#include "ActorManager.hpp"
#include "AudioManager.hpp"

namespace hny {

	/* Helper class for keeping score */
	struct ScoreEntry {
		ScoreEntry(unsigned int s, time_t t, bool n = false) : Score(s), Time(t), New(n) {}

		unsigned int Score;
		time_t Time;
		bool New;
	};

	/* Predicate for std::sort*/
	struct ScorePredicateLess {
		bool operator() (const ScoreEntry& a, const ScoreEntry& b) { return a.Score < b.Score; }
	};

	// Typedefs
	typedef std::vector<ScoreEntry> ScoreVector;

	typedef boost::shared_ptr<Actor> ActorPtr;
	typedef std::vector<ActorPtr> ActorPtrVector;

	typedef std::map<std::string, HTEXTURE> TextureMap;
	typedef std::pair<std::string, HTEXTURE> TexPair;

	typedef std::map<std::string, HEFFECT> EffectMap;

	// Forward declarations
	class RocketSpawner;

	/* The WORLD! */
	class World
	{
	public:
		World(HGE* hge);
		~World();

		void Initialize();
		void LoadTextures();
		void LoadEffects();

		bool Update(float dt);
		bool Draw();

		void CollideActors();

		void SpawnExplosion(hgeVector position,  int combo = 0, float velocity = 100.0f, float radius = 100.0f);
		void SpawnComboText(const hgeVector pos, int combo);

		void CalculateScore(int score);

		void StartNewGame();
		void EndGame();

		void LoadHighScores();
		void UpdateHighScores();
		void SaveHighScores();

		void PlayRocketSound();
		void PlayExplosionSound();

		ScoreVector GetHighScores();

		HTEXTURE GetTexture(const std::string& name);

	private:
		// Do these need deleting or does HGE automagically take care of it??
		hgeSprite *mBackgroundSprite;
		hgeSprite *mSidebarSpriteLeft;
		hgeSprite *mSidebarSpriteRight;
		hgeSprite *mLogoSprite;
		hgeSprite *mSplashSprite;
		hgeAnimation* mParticleSprites;
		hgeSprite* pSprite;

		HGE* mHge;
		//

		RocketSpawner* mRocketSpawner;
		TextureMap mTextures;
		TextCollection mTextCollection;
		Menu* mMenu;

		Audio* mMusic;
		std::vector<Audio*> mExplosionSounds;
		std::vector<Audio*> mRocketSounds;

		bool mHavePlayedWarning;

		unsigned int mScore;
		unsigned int mCombos;
		unsigned int mHighestCombo;
		float mMultiplier;

		float mComboTime;
		float mComboAccum;

		bool mMenuActive;
		bool mGameStarted;
		bool mGameEnded;

		bool mFinished;

		float mTimeLeft;

		bool mMusicPlaying;
		float mVolumeMusic;
		float mVolumeSound;

		float mSplashTime;
		float mSplashAccum;
		float mSplashAlpha;
		bool mShowSplash;

		ScoreVector mHighScores;

	};
}
